﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xyz.Framework.Shared.DataContracts.DTO;
using Xyz.Framework.Server.DataAcessLayer;
using Xyz.Framework.Server.DomainObjects;
using System.Data.Objects;
using Xyz.Framework.Shared.DataContracts.Enums;



namespace Xyz.Framework.Server.Security
{
    public class AuthenticationManagement
    {
        public const string CONNECTION_STRING = "name = HRSEntities";
        public const string CONTAINER_NAME = "HRSEntities";
        public static AuthenticatedUserDTO ValidateUser(string username, string password)
        {
            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
                throw new Exception("Kullanıcı adı veya parola boş olamaz");

            using (DataBaseContext db = new DataBaseContext(CONNECTION_STRING, CONTAINER_NAME))
            {
                ObjectSet<User> _userSet = db.CreateObjectSet<User>();
                ObjectSet<UserRoleMembership> _userRoleMembershipSet = db.CreateObjectSet<UserRoleMembership>();
                ObjectSet<Role> _roleSet = db.CreateObjectSet<Role>();
                ObjectSet<RoleAuthority> _roleAuthoritySet = db.CreateObjectSet<RoleAuthority>();
                ObjectSet<WebApplication> _webApplicationSet = db.CreateObjectSet<WebApplication>();
                ObjectSet<RoleWebApplication> _roleWebApplicationSet = db.CreateObjectSet<RoleWebApplication>();

                AuthenticatedUserDTO _result = new AuthenticatedUserDTO();


                var _query = from u in _userSet
                             join rm2 in
                                 (
                                     from rm in _userRoleMembershipSet
                                     join r in _roleSet on rm.RoleId equals r.Id
                                     join ra in _roleAuthoritySet on r.Id equals ra.RoleId into authorities
                                     join rw in
                                         (
                                            from rwa in _roleWebApplicationSet
                                            join w in _webApplicationSet on rwa.WebApplicationId equals w.Id
                                            select new
                                            {
                                                rwa.RoleId,
                                                webapp = w
                                            }

                                         ) on r.Id equals rw.RoleId into webapps
                                     select new
                                     {
                                         UserId = rm.UserId,
                                         role = r,
                                         authorities = authorities,
                                         applications = webapps,
                                     }
                                 ) on u.Id equals rm2.UserId into roles
                             where u.UserName == username && u.Password == password && u.State == true
                             select new
                             {
                                 user = u,
                                 roles
                             };
                var _queryResult = _query.FirstOrDefault();
                if (_queryResult == null || _queryResult.user == null)
                    throw new Exception("Kullanıcı adı veya şifre hatalı.");

                UserDetailsDTO _userdetails = new UserDetailsDTO()
                {
                    Id = _queryResult.user.Id,
                    Email = _queryResult.user.Email,
                    Password = _queryResult.user.Password,
                    Sms = _queryResult.user.Sms,
                    UserName = _queryResult.user.UserName,
                };
                _result.User = _userdetails;
                if (_queryResult.roles != null && _queryResult.roles.Count() > 0)
                {
                    List<RoleDetailsDTO> _rolelist = new List<RoleDetailsDTO>();
                    foreach (var roleitem in _queryResult.roles)
                    {
                        RoleDetailsDTO _roledetailDTO = new RoleDetailsDTO();

                        _roledetailDTO.RoleId = roleitem.role.Id;
                        _roledetailDTO.RoleName = roleitem.role.Name;
                        if (roleitem.authorities != null && roleitem.authorities.Count() > 0)
                        {
                            List<EFrameworkAuthority> _authList = new List<EFrameworkAuthority>();
                            foreach (var authitem in roleitem.authorities)
                            {
                                _authList.Add((EFrameworkAuthority)authitem.AuthorityId);
                            }
                            _roledetailDTO.RoleAuthorities = _authList.ToArray();
                        }

                        if (roleitem.applications != null && roleitem.applications.Count() > 0)
                        {
                            List<WebApplicationDTO> _applist = new List<WebApplicationDTO>();
                            foreach (var appitem in roleitem.applications)
                            {
                                _applist.Add(new WebApplicationDTO()
                                {
                                    Enabled = appitem.webapp.Enabled,
                                    Id = appitem.webapp.Id,
                                    Name = appitem.webapp.Name,
                                    Uri = appitem.webapp.Uri
                                });
                            }
                            _roledetailDTO.AuthorizedApplications = _applist.ToArray();
                        }
                        _rolelist.Add(_roledetailDTO);
                    }
                    _result.Roles = _rolelist.ToArray();
                }
                AuthenticatedUser.CreateCurrentUser(_result);
                return _result;
            }
        }
    }
}
